package com.xinyan.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StreamUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 处理输入流只能读第一次问题
 */
@Slf4j
public class BodyCopyHttpServletRequestWrapper  extends HttpServletRequestWrapper {

    private final String UTF_8 = "UTF-8";

    /**
     * 输入流
     */
    private final byte[] bytes;

    public BodyCopyHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        // 备份
        // 如不关心字符集，也可以直接在方法cloneInputStream()中byteArrayOutputStream.toByteArray()
        bytes = getBodyString(request).getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 获取请求Body
     * @param request
     * @return
     */
    private String getBodyString(final ServletRequest request) {
        StringBuffer sb = new StringBuffer();
        try (
                InputStream inputStream = cloneInputStream(request.getInputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(UTF_8)))
        ) {
            String line = "";
            while (Objects.nonNull((line = reader.readLine()))) {
                sb.append(line);
            }
        } catch (IOException e) {
            throw new RuntimeException("输入流读取出错");
        }
        return sb.toString();
    }

    /**
     * 输入流复制
     * @param inputStream
     * @return
     */
    private InputStream cloneInputStream(ServletInputStream inputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            StreamUtils.copy(inputStream, byteArrayOutputStream);
        } catch (IOException e) {
            log.info("=======输入流赋值失败=======");
            throw new RuntimeException(e);
        }
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    /**
     * 重写父方法，返回新的输入流
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream copyStream = new ByteArrayInputStream(bytes);
        /**
         * 新的输入流
         */
        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return copyStream.read();
            }

            /**
             * 未读状态
             * @return
             */
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }






}
